<?php
defined('_VISIT_URL_') or exit('No direct script access allowed');

class intercept
{
	public function preHandle($controlTeam, $controller, $funcName) {
		$interface = '/' . $controlTeam . '/' . $controller . '/' . $funcName;

		//防跨域检查
		if (!isset($_SERVER['HTTP_REFERER']) || !strstr($_SERVER['HTTP_REFERER'], _VISIT_URL_)) {
			util::writeLog($interface . '，跨域');
			return util::getVisitError('非法访问');
		}

		//防止频繁访问
		/*$result = $this->accessLimit();
		if ($result != null) {
			return $result;
		}*/

		//过滤掉部分接口的token检查
		if ($this->filterManager($interface)) {
			util::writeLog($interface);
			return null;
		}

		//管理后台接口验证流程 —— 开始
		$token = util::decrypt(getServer('HTTP_TOKEN'));
		if (empty($token)) {
			util::writeLog($interface . '，token为空');
			return util::getVisitError('非法访问1，请重新登录');
		}

		$temp = explode('[@#%&]', $token);
		if (count($temp) != 6) {
			util::writeLog($interface . '，token项数错误');
			return util::getVisitError('非法访问2，请重新登录');
		}

		$userid = $temp[0];
		$username = $temp[1];
		$pwd = $temp[2];
		$name = $temp[3];
		$time = $temp[4];
		$random = $temp[5];
		if (empty($userid) || empty($username) || empty($pwd) || empty($name) || empty($time) || empty($random)) {
			util::writeLog($userid . '，' . $interface . '，token至少一项为空');
			return util::getVisitError('非法访问3，请重新登录');
		}

		if (strlen($userid) != 32 || strlen($time) != 10 || strlen($random) != 6) {
			util::writeLog($userid . '，' . $interface . '，随机数格式不正确');
			return util::getVisitError('非法访问4，请重新登录');
		}

		if (strlen($name) < 2 || strlen($name) > 16) {
			util::writeLog($userid . '，' . $interface . '，姓名格式不正确');
			return util::getVisitError('非法访问5，请重新登录');
		}

		$now = time();
		//超过30分钟不操作，账号关闭
		if ($time + _VALID_OVERTIME_ < $now) {
			util::writeLog($userid . '，' . $interface . '，超过30分钟不操作');
			return util::getVisitError('非法访问6，请重新登录');
		}

		//每15分钟验证一次账号的有效性
		if ($time + _VALID_INTERVAL_ < $now) {
			$rst = new sqlcon();
			$user = $rst->getInfo('id, flag', 'user', "isuse = 1 and userid = '" . $userid . "' and username = '" . $username . "' and password = '" . $pwd . "'");
			if (empty($user)) {
				util::writeLog($userid . '，' . $interface . '，用户ID已关闭');
		    	return util::getVisitError('非法访问7，请重新登录');
			}

			if (empty($user['flag']) || $user['flag'] != $random) {
				util::writeLog($userid . '，' . $interface . '，用户已在别处登录');
		    	return util::getVisitError('非法访问8，请重新登录');
			}

			//若被代班者token不为空，检查被代班者的有效性，若有效则重置被代班者的最新代班时间
			/*$duty = util::decrypt(getServer('HTTP_DUTY'));
			if (!empty($duty)) {
				$temp = explode('[@#%&]', $duty);
				if (count($temp) != 2) {
					util::writeLog($interface . '，duty项数错误');
					return util::getVisitError('非法访问8，请重新登录');
				}

				$dutyid = $temp[0];
				$dutyname = $temp[1];
				$info = $rst->getInfo('id', 'user', "dutystatus = 2 and userid = '" . $dutyid . "' and username = '" . $dutyname . "'");
				if (!empty($info)) {
					$rst->clearCollect();
					$rst->addCollect('dutytime', date('Y-m-d H:i:s'));
					$rst->addCollect('userid', $dutyid);
					$rst->updateInfo('user');
				}
				else {
					util::writeLog($interface . '，代班权限被取消');
					return util::getVisitError('非法访问9，请重新登录');
				}
			}*/

		    util::writeLog($userid . '，' . $interface . '，用户ID超时验证');
		}

		util::writeLog($userid . '，' . $interface);
		return null;
	}

	public function nextHandle($controlTeam, $controller, $funcName, $result) {
		//过滤掉部分接口的token检查
		$interface = '/' . $controlTeam . '/' . $controller . '/' . $funcName;
		if ($this->filterManager($interface)) {
			return $result;
		}

		$token = util::decrypt(getServer('HTTP_TOKEN'));
		$temp = explode('[@#%&]', $token);

		//若超过15分钟，则更新token中的时间
		$now = time();
		if ($temp[4] + _VALID_INTERVAL_ < $now) {
			$result['lyToken'] = util::encrypt($temp[0] . '[@#%&]' . $temp[1] . '[@#%&]' . $temp[2] . '[@#%&]' . $temp[3] . '[@#%&]' . $now . '[@#%&]' . $temp[5]);
		}

		return $result;
	}

	private function filterManager($interface) {
		if ($interface == '/manager/account/login' || strpos($interface, '/platform/') !== FALSE) {
			return true;
		}

		return false;
	}

	private function accessLimit() {
		$redis = new Redis();
		$redis->connect('127.0.0.1', 6379);

		$ip = util::getIP();
		$list = $redis->lrange('forbid_ip', 0, -1);
		for ($i = 0; $i < count($list); $i++) {
			if (strpos($list[$i], $ip) !== FALSE) {
				$redis->close();

				util::writeLog($ip . '，被禁IP再度访问');
				return util::getVisitError('服务器繁忙');
			}
		}

		$key = $ip . '_' . date('YmdHis');
		$count = intval($redis->get($key));
		if (empty($count)) {
			$redis->set($key, 1);
			$redis->expire($key, 120);
		}
		else if ($count < _MAX_LIMIT_NUMS_) {
			$redis->incr($key);
		}
		else {
			$redis->lpush('forbid_ip', $key);
			$redis->close();

			util::writeLog($ip . '，被禁止访问');
			return util::getVisitError('访问太频繁，请稍后再试');
		}

		$redis->close();

		return null;
	}
}